package cn.edu.fzu.delivery.service.impl;

import cn.edu.fzu.delivery.common.MD5Util;
import cn.edu.fzu.delivery.domain.entity.Customer;
import cn.edu.fzu.delivery.domain.entity.SysUser;
import cn.edu.fzu.delivery.domain.enums.SexEnum;
import cn.edu.fzu.delivery.domain.enums.UserStatusEnum;
import cn.edu.fzu.delivery.domain.enums.UserTypeEnum;
import cn.edu.fzu.delivery.exception.ServiceException;
import cn.edu.fzu.delivery.helper.EmailHelper;
import cn.edu.fzu.delivery.mapper.CustomerMapper;
import cn.edu.fzu.delivery.mapper.SysUserMapper;
import cn.edu.fzu.delivery.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Random;

/**
 * @author fangxin
 * @date 2022/9/10
 */
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private SysUserMapper        sysUserMapper;
    @Resource
    private CustomerMapper       customerMapper;

    @Resource
    private EmailHelper          emailHelper;

    private static final Integer INIT_PWD_LEN = 10;

    /**
     * 随机密码生成
     */
    private static String randomPassword() {
        StringBuffer pwd = new StringBuffer();
        Random rand = new Random();
        for (int i = 0; i < INIT_PWD_LEN; i++) {
            //从大写字母.小写字母.数字中随机取值
            int choice = rand.nextInt(3);
            int lowercase = rand.nextInt(26) + 65;
            int uppercase = rand.nextInt(26) + 97;
            int figure = rand.nextInt(10) + 48;
            switch (choice) {
                case 0:
                    pwd.append((char) lowercase);
                    break;
                case 1:
                    pwd.append((char) uppercase);
                    break;
                case 2:
                    pwd.append((char) figure);
            }
        }
        return pwd.toString();
    }


    @Override
    public List<SysUser> listSysUser(Long networkId, String name, UserTypeEnum type, UserStatusEnum status,
                                     String phone, String email, SysUser currentUser) {
        if (currentUser != null) {
            // 快递员不能查询
            UserTypeEnum userType = currentUser.getType();
            if (userType == UserTypeEnum.EXPRESS) {
                throw new ServiceException("没有访问权限");
            }
            // 网点管理员只能查询自己网点的人员，且不能查询超级管理员
            if (userType == UserTypeEnum.NET_ADMIN) {
                if (networkId == null || (!Objects.equals(networkId, currentUser.getNetwork().getId()))) {
                    throw new ServiceException("网点管理员只能查询自己网点的人员");
                }
                if (type == null || type == UserTypeEnum.SUPER_ADMIN) {
                    throw new ServiceException("没有超级管理员权限");
                }
            }
        }
        return sysUserMapper.list(networkId, name, type, status, phone, email);
    }


    @Override
    public SysUser getSysUserByEmail(String email) {
        return sysUserMapper.getByEmail(email);
    }


    @Override
    public SysUser getSysUserByPhone(String phone) {
        return sysUserMapper.getByPhone(phone);
    }


    @Override
    public SysUser getSysUserByDingId(String dingId) {
        return sysUserMapper.getByDingId(dingId);
    }


    public void updateSysUserInfo(Long id, String email, String name, SexEnum sex, Date birth, String phone,
                                  String address, UserTypeEnum type, UserStatusEnum status, Long networkId,
                                  SysUser currentUser) {
        UserTypeEnum currentUserType = currentUser.getType();

        if (currentUserType == UserTypeEnum.NET_ADMIN) {
            SysUser targetUser = sysUserMapper.getById(id);
            if (!Objects.equals(targetUser.getNetwork().getId(), currentUser.getNetwork().getId())) {
                throw new ServiceException("只能修改自己网点的人员信息");
            }
        } else if (currentUserType == UserTypeEnum.EXPRESS) {
            throw new ServiceException("需要权限：超级管理员或网点管理员");
        }

        if (type != null && currentUserType.getValue() < type.getValue()) {
            throw new ServiceException("无权赋予高于您本身的权限");
        }

        SysUser sysUser = getSysUserByEmail(email);
        if (sysUser != null && !Objects.equals(sysUser.getId(), id)) {
            throw new ServiceException("该邮箱已被注册");
        }

        // 保证一个网点最多一个网点管理员
        if (networkId != null && type == UserTypeEnum.NET_ADMIN) {
            List<SysUser> netAdmins = sysUserMapper.list(networkId, null, UserTypeEnum.NET_ADMIN, null, null, null);
            // 网点存在其他网点管理员
            if (!netAdmins.isEmpty() && !Objects.equals(id, netAdmins.get(0).getId())) {
                throw new ServiceException("该网点已有网点管理员");
            }
        }

        // 升级为超级管理员则不分配网点
        if (type == UserTypeEnum.SUPER_ADMIN) {
            networkId = null;
        }

        Integer update = sysUserMapper.update(id, email, null, name, sex, birth, phone, address, null, type, status,
                networkId);
        if (update == 0) {
            throw new ServiceException("用户不存在");
        }
    }


    @Override
    public void addSysUser(String email, String name, SexEnum sex, Date birth, String phone, String address,
                           UserTypeEnum type, Long networkId, SysUser currentUser) {
        if (currentUser.getType() != UserTypeEnum.SUPER_ADMIN) {
            throw new ServiceException("没有访问权限");
        }

        SysUser sysUser = getSysUserByEmail(email);
        if (sysUser != null) {
            throw new ServiceException("该邮箱已被注册");
        }

        // 保证一个网点最多一个网点管理员
        if (networkId != null && type == UserTypeEnum.NET_ADMIN) {
            List<SysUser> netAdmins = sysUserMapper.list(networkId, null, UserTypeEnum.NET_ADMIN, null, null, null);
            // 网点存在网点管理员
            if (!netAdmins.isEmpty()) {
                throw new ServiceException("该网点已有网点管理员");
            }
        }

        String password = randomPassword(); // 初始密码
        String passwordMD5 = MD5Util.MD5Encode(password);
        UserStatusEnum status = UserStatusEnum.NORMAL; // 初始状态
        Integer add = sysUserMapper.add(email, passwordMD5, name, sex, birth, phone, address, type, status, networkId);
        if (add == 0) {
            throw new ServiceException("参数错误");
        }
        if (add == 1) {
            String content = "您的账户（" + email + "，" + type.getDesc() + "\"）注册成功，初始密码为\r\n" + password
                    + "\r\n，请尽快登录系统修改密码";
            emailHelper.sendMail(email, "注册成功", content);
        }
    }


    @Override
    public void updateSysUserStatus(Long id, UserStatusEnum status, SysUser currentUser) {
        if (currentUser.getType() == UserTypeEnum.NET_ADMIN) {
            SysUser targetUser = sysUserMapper.getById(id);
            if (!Objects.equals(targetUser.getNetwork().getId(), currentUser.getNetwork().getId())) {
                throw new ServiceException("只能修改自己网点的快递员信息");
            }
            if (targetUser.getType().getValue() > currentUser.getType().getValue()) {
                throw new ServiceException("不能修改更高级别的用户");
            }
        } else if (currentUser.getType() == UserTypeEnum.EXPRESS) {
            throw new ServiceException("快递员没有修改权限");
        }

        Integer update = sysUserMapper.updateStatus(id, status);
        if (update == 0) {
            throw new ServiceException("用户不存在");
        }
    }


    @Override
    public void updateSysUserDingId(String email, String dingId) {
        sysUserMapper.updateDingId(email, dingId);
    }


    @Override
    public Customer getCustomerByEmail(String email) {
        return customerMapper.getByEmail(email);
    }


    @Override
    public void addCustomer(String email, String password, String name, SexEnum sex, String birth, String phone,
                            String imageUrl) {
        Customer customer = customerMapper.getByEmail(email);
        if (customer != null) {
            throw new ServiceException("该邮箱已被注册，请更换邮箱");
        }
        customer = customerMapper.getByPhone(phone);
        if (customer != null) {
            throw new ServiceException("该手机号已被绑定，请更换手机号");
        }
        customerMapper.insert(email, MD5Util.MD5Encode(password), name, sex, birth, phone, imageUrl,
                UserStatusEnum.NORMAL);
    }


    @Override
    public void updateCustomer(Long id, String name, SexEnum sex, String birth, String imageUrl) {
        customerMapper.update(id, null, name, sex, birth, null, imageUrl, null);
    }


    @Override
    public void updateCustomerPassword(String email, String password) {
        Customer customer = customerMapper.getByEmail(email);
        if (customer == null) {
            throw new ServiceException("该账号未注册");
        }
        customerMapper.update(customer.getId(), MD5Util.MD5Encode(password), null, null, null, null, null, null);
    }


    @Override
    public void updateSysPassword(String email, String password) {
        SysUser sysUser = sysUserMapper.getByEmail(email);
        if (sysUser == null) {
            throw new ServiceException("该账号未注册");
        }

        sysUserMapper.update(sysUser.getId(), null, MD5Util.MD5Encode(password), null, null, null, null, null, null,
                null, null, null);
    }


    @Override
    public Customer getCustomerByPhone(String phone) {
        return customerMapper.getByPhone(phone);
    }


    @Override
    public List<Customer> listCustomer(String name, String email, SexEnum sex, String phone, UserStatusEnum status,
                                       SysUser currentUser) {
        if (currentUser.getType() != UserTypeEnum.SUPER_ADMIN) {
            throw new ServiceException("需要权限：超级管理员");
        }
        return customerMapper.list(name, email, sex, phone, status);
    }


    @Override
    public void updateCustomerStatus(Long id, UserStatusEnum status, SysUser currentUser) {
        if (currentUser.getType() != UserTypeEnum.SUPER_ADMIN) {
            throw new ServiceException("需要权限：超级管理员");
        }
        customerMapper.update(id, null, null, null, null, null, null, status);
    }


    @Override
    public void updateImageUrl(String imageUrl, Object currentUser) {
        if (currentUser == null) {
            throw new ServiceException("未登录");
        }
        if (currentUser instanceof SysUser) {
            SysUser sysUser = (SysUser) currentUser;
            sysUserMapper.update(sysUser.getId(), null, null, null, null, null, null, null, imageUrl, null, null, null);
        } else {
            Customer customer = (Customer) currentUser;
            customerMapper.update(customer.getId(), null, null, null, null, null, imageUrl, null);
        }
    }
}
